<template>
  <el-popover
    placement="bottom-start"
    :width="width"
    trigger="click"
    @show="isShow = true"
    @hide="isShow = false">
    <div class="tree-select-container">
      <div class="tree-select-header">
        <el-input
          placeholder="输入关键字进行过滤"
          v-model="filterText"
          size="mini"
          class="mb8">
        </el-input>
        <el-button size="mini" @click="_selectAll">全选</el-button>
        <el-button size="mini" @click="_selectReverse">反选</el-button>
        <el-button size="mini" @click="_clear">清除</el-button>
      </div>
      <el-scrollbar wrap-style="max-height: 300px;">
        <el-tree
          :data="selectList"
          show-checkbox
          :node-key="fieldValue"
          ref="treeSelect"
          :default-checked-keys="value ? value : []"
          :props="defaultProps"
          :filter-node-method="_filterNode"
          :check-on-click-node="true"
          @check="_treeSelectCheck">
        </el-tree>
      </el-scrollbar>
    </div>
    <div class="tree-select-input" slot="reference">
      <el-input
        v-model="selectValue"
        :placeholder="placeholder"
        :class="[selectName.length ? 'hide-text' : '']"
        :size="size"
        readonly>
        <i
          :class="['el-icon-arrow-down el-input__icon', isShow ? 'isShow' : '']"
          slot="suffix">
        </i>
      </el-input>
      <span class="tree-select-text">{{selectName}}</span>
    </div>
  </el-popover>
</template>

<script>
export default {
  name: 'el-tree-select',
  props: {
    data: {
      default: [],
      type: Array
    },
    value: {
      default: null
    },
    displayValue: {
      default: 'label',
      type: String
    },
    fieldValue: {
      default: 'id',
      type: String
    },
    placeholder: {
      default: '',
      type: String
    },
    width: {
      default: 280,
      type: Number
    },
    size: {
      default: 'small',
      type: String
    },
    defaultProps: {
      default: () => {
        return {
          children: 'children',
          label: 'label'
        }
      },
      type: Object
    },
    specialHandlerValue: {
      default: false,
      type: Boolean
    }
  },
  data () {
    return {
      isShow: false,
      selectList: [],
      selectValue: null,
      selectName: '',
      filterText: ''
    }
  },
  created () {
    let vm = this;
    vm.selectList = vm.data;
    vm.firstLoad = true;
    vm.selectValue = Array.isArray(vm.value) ? vm.value.join(',') : vm.value;
  },
  mounted () {
    let vm = this;
    vm._treeSelectChange(true);
  },
  watch: {
    data (val) {
      this.selectList = val;
    },
    value (val, newval) {
      let vm = this; 
      if (vm.needHandle) {
        vm._setCheckedKeys(Array.isArray(val) ? val : val ? val.split(',') : []);
        vm._treeSelectChange();
      }
      vm.needHandle = true;
    },
    selectValue (val) {
      if (this.specialHandlerValue) {
        this._handlerRegionCheckData();
      } else {
        this.needHandle = false;
        this.$emit('update:value', val ? val.split(',') : []);
        if (this.firstLoad) {
          this.firstLoad = false;
        } else {
          this.$emit('change', val ? val.split(',') : []);
        }
      }
    },
    filterText(val) {
      this.$refs.treeSelect.filter(val);
    }
  },
  methods: {
    // tree check
    _treeSelectCheck (currNode, treeData) {
      let vm = this;
      vm._treeSelectChange();
    },
    // tree change
    _treeSelectChange (unUpdateValue) {
      let vm = this;
      let name = '';
      let checkedNodes = vm._getCheckedNodes();
      let checkedKeys = vm._getCheckedKeys();
      if (checkedNodes.length === 0) {
        name = '';
      } else if (checkedNodes.length === 1) {
        name = `${checkedNodes[0][vm.displayValue]}`;
      } else {
        name = `选择了 ${checkedNodes.length} 项 ${vm.placeholder}`;
      }
      if (!unUpdateValue) {
        vm.$set(vm, 'selectValue', checkedKeys.join(','));
      }
      vm.$set(vm, 'selectName', name);
      vm.$emit('checkedNodes',checkedNodes);
    },
    // 筛选
    _filterNode (value, data, node) {
      if (!value) return true;
      return data[this.defaultProps.label].indexOf(value) !== -1;
    },
    // 全选
    _selectAll () {
      let vm = this;
      let selectValue = vm._deepGetTreeKeys(vm.selectList);
      vm._setCheckedKeys(selectValue);
      vm._treeSelectChange();
    },
    // 反选
    _selectReverse () {
      let vm = this;
      let currSelect = vm._getCheckedKeys();
      let selectValue = [];
      vm._deepGetTreeKeys(vm.selectList).map(item => {
        if (!currSelect.includes(item)) {
          selectValue.push(item);
        }
      });
      vm._setCheckedKeys(selectValue);
      vm._treeSelectChange();
    },
    // 清除
    _clear () {
      this._setCheckedKeys([]);
      this._treeSelectChange();
    },
    // 获取当前选中节点
    _getCheckedNodes() {
      return this.$refs.treeSelect.getCheckedNodes();
    },
    // 获取当前选中keys
    _getCheckedKeys() {
      return this.$refs.treeSelect.getCheckedKeys();
    },
    // 通过key设置选中项
    _setCheckedKeys(keyArr) {
      this.$refs.treeSelect.setCheckedKeys(keyArr);
    },
    // 递归获取tree所有key的值
    _deepGetTreeKeys (arrObj, keysArr = []) {
      let vm = this;
      arrObj.forEach(item => {
        keysArr.push(item[vm.fieldValue]);
        if (item.children && item.children.length > 0) {
          vm._deepGetTreeKeys(item.children, keysArr);
        }
      });
      return keysArr;
    },
    // 处理地域数据（特殊，不可共用）
    _handlerRegionCheckData () {
      let vm = this;
      let selectArr = vm.$refs.treeSelect.getCheckedKeys(true);
      let newSelectArr = [];
      if (selectArr.length > 0) {
        vm.selectList.forEach(item => {
          let city = [];
          item.children.forEach(childItem => {
            if (selectArr.includes(childItem.value)) {
              city.push(childItem.value);
            }
          });
          if (city.length > 0) {
            newSelectArr.push({'province': item.value, 'city': city.length == item.children.length ? 'all' : city.join(',')});
          }
        });
      }
      vm.needHandle = false;
      vm.$emit('update:value', newSelectArr);
      vm.$emit('change', newSelectArr);
    }
  }
}
</script>

<style lang="scss">
  .tree-select-container {
    .tree-select-header {
      padding-bottom: 6px;
      border-bottom: #eee 1px solid;
    }
    // .el-scrollbar {
    //   .el-scrollbar__wrap {
    //     margin-bottom: -16px !important;
    //     margin-right: -16px !important;
    //   }
    // }
  }
  .tree-select-input {
    position: relative;
    .hide-text {
      .el-input__inner {
        text-indent: -99999em;
      }
    }
    .el-icon-arrow-down {
      font-size: 14px;
      transition: all .3s;
      &.isShow {
        transform: rotate(-180deg);
      }
    }
    .tree-select-text {
      position: absolute;
      top: 50%;
      left: 15px;
      right: 15px;
      transform: translateY(-50%);
      font-size: 12px;
      color: #666;
    }
  }
</style>